package com.example.aigc_education.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.aigc_education.anno.RequestKeyParam;
import com.example.aigc_education.anno.RequestLock;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.constant.CacheConstants;
import com.example.aigc_education.domain.*;
import com.example.aigc_education.domain.dto.PageDTO;
import com.example.aigc_education.domain.dto.query.PlanQuery;
import com.example.aigc_education.domain.dto.query.ShowPlanQuery;
import com.example.aigc_education.domain.request.UpdatePlanCurrentModuleRequest;
import com.example.aigc_education.domain.request.UpdatePlanTimeRequest;
import com.example.aigc_education.domain.vo.*;
import com.example.aigc_education.service.*;
import com.example.aigc_education.utils.RedisCache;
import com.example.aigc_education.utils.ResultUtil;
import com.example.aigc_education.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 计划控制器类，负责处理计划相关的HTTP请求。
 */
@Slf4j
@RequestMapping("/plan")
@RestController
public class PlanController {

    @Resource
    private PlanService planService;

    @Resource
    private CourseService courseService;

    @Resource
    private QuestionService questionService;

    @Resource
    private UserService userService;

    @Resource
    private TodoService todoService;

    @Resource
    private RedisCache redisCache;

    /**
     * 搜索学习计划事件
     *
     * 通过调用planService的queryPlan方法
     * 对学习计划进行模糊搜索查询，根据学习计划名字来进行模糊查询
     *
     * @param planName      学习计划名字
     * @return              学习计划集合，排序顺序是按照创建时间倒序排序
     */
    @GetMapping("/queryPlan")
    public ResultUtil queryPlanByName(String planName){
        List<PlanVO> plans = planService.queryPlan(planName);

        return ResultUtil.success(plans);
    }

    /**
     * 搜索学习计划事件V2
     *
     * 通过调用planService的queryPlan方法
     * 对学习计划进行模糊搜索查询，根据学习计划名字来进行模糊查询
     *
     * @param planName      学习计划名字
     * @return              学习计划集合，排序顺序是按照创建时间倒序排序
     */
    @GetMapping("/queryPlan/v2")
    public ResultUtil queryPlanByNameV2(String planName){
        Long userId = SecurityUtils.getUserId();
        List<ListPlanVO> plans = planService.queryPlanV2(planName,userId);

        return ResultUtil.success(plans);
    }


    /**
     * 删除计划
     * @param planId 计划id
     * @return 返回删除计划结果
     */
    @RequestLock(prefix = "deletePlan", expire = 3)
    @DeleteMapping("/deletePlan")
    public ResultUtil deletePlan(@RequestKeyParam Long planId) {
        planService.deletePlan(planId);

        return ResultUtil.success("学习计划删除成功");
    }

    /**
     * 获取当前计划下测验主题的测验情况
     * @param planId    当前计划id
     * @return          TestInfoVO对象，包含总问题数、未完成问题数、已完成问题数
     */
//    @GetMapping("/getTestInfo")
//    public ResultUtil getTestInfo(Long planId){
//        TestInfoDTO testInfoVO = planService.getTestInfo(planId);
//
//        return ResultUtil.success(testInfoVO);
//    }

    /**
     *  获取当前用户下的所有的Plan计划
     * @return      PlanVO集合，根据创建时间倒序排序返回
     */
    @GetMapping("/selectAll")
    public ResultUtil selectAllPlan(){
        Long userId = SecurityUtils.getUserId();
        List<PlanVO> planVOS = planService.getAllPlan(userId);

        return ResultUtil.success(planVOS);
    }

    /**
     *  获取当前用户下的所有的Plan计划  V2
     * @return      ListPlanVO集合，根据创建时间倒序排序返回
     */
    @PostMapping("/select/all/v2")
    public ResultUtil selectAllPlanV2(@RequestBody ShowPlanQuery showPlanQuery){
        Long userId = SecurityUtils.getUserId();
        return ResultUtil.success(planService.getAllPlanV2(userId,showPlanQuery));
    }


    /**
     *  获取当前用户下的计划轮播
     * @return      ListPlanVO集合，根据创建时间倒序排序返回
     */
    @GetMapping("/carousel")
    public ResultUtil planCarousel(){
        Long userId = SecurityUtils.getUserId();
        return ResultUtil.success(planService.carousel(userId));
    }

    /**
     * 生成计划
     * @param planId 计划id
     * @param courseName 课程名称
     * @param studyCapacity 学生自身学习能力
     * @return 返回设计计划结果
     */
    @PostMapping("/design")
    public ResultUtil generatePlan(Long planId, String courseName, String studyCapacity) {
        Long userId = SecurityUtils.getUserId();
        Course course = courseService.getOne(new LambdaQueryWrapper<Course>().eq(Course::getCourseName, courseName));
        if (course == null)
            throw new BusinessException("课程不存在");
//        int result = planService.generatePlan(userId, planId, course, studyCapacity);
//        if (result < 0)
//            throw new BusinessException("生成计划失败");
        // 生成计划
        return ResultUtil.success();
    }





    /**
     * 获取能力测验内容
     * @param planId 计划id
     * @param testContent 试题完成内容
     * @return 返回能力测验结果
     */
    @GetMapping("/getTestCapacity")
    public ResultUtil getTestCapacity(Long planId, String testContent) {
        Long userId = SecurityUtils.getUserId();
//        String actualCapacity = planService.getTestCapacity(userId, planId, testContent);
//        if (StringUtils.isEmpty(actualCapacity))
//            throw new BusinessException("获取能力测验失败");

        HashMap<String, Object> data = new HashMap<>();
//        data.put("AIAnswer", actualCapacity);
        return ResultUtil.success("AI评价成功", data);
    }


    /**
     * 更新计划
     * @param plan 计划对象
     * @return 返回更新计划结果
     */
//    @PutMapping("/update")
//    public ResultUtil updatePlan(@RequestBody Plan plan) {
//        return ResultUtil.success();
//    }


    /**
     * 获取计划进度
     * @param planId 计划id
     * @return 返回计划进度结果
     */
    @PostMapping("/getPlanProcess")
    public ResultUtil getPlanProcess(Long planId) {
        // 创建LambdaQueryWrapper对象
        LambdaQueryWrapper<Todo> queryWrapper = new LambdaQueryWrapper<>();
        // 添加查询条件并进行分组
        queryWrapper.eq(Todo::getPlanId, planId).groupBy(Todo::getChapter);
        // 使用TodoService进行查询
        List<Object> chapterList = todoService.listObjs(queryWrapper.select(Todo::getChapter));
        List<TodoCardVo> todoCardList = new ArrayList<>();
        // 输出查询结果
        chapterList.forEach(chapter -> {
            TodoCardVo todoCardVo = new TodoCardVo();
            List<Object> knowledgePointers = todoService.listObjs(new LambdaQueryWrapper<Todo>()
                    .eq(Todo::getPlanId, planId)
                    .eq(Todo::getChapter, chapter)
                    .select(Todo::getKnowledgepointer));
            List<String> knowledgePointersStr = knowledgePointers.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());
            todoCardVo.setChapter((String) chapter);
            todoCardVo.setKnowledgePointers(knowledgePointersStr);
            // 判断是否为空
            String color = redisCache.getCacheObject(CacheConstants.TODO_COMPLETE_KEY + planId + ":" + chapter);
            todoCardVo.setColor(color);
            todoCardList.add(todoCardVo);
        });

        log.info("todo卡片展示进度情况:{}", todoCardList);
        return ResultUtil.success(todoCardList);
    }


    /**
     * 删除计划
     * @param planId 计划id
     * @return 返回删除计划结果
     */
//    @DeleteMapping("/delete")
//    public ResultUtil deletePlan(Long planId) {
//        // 不需要校验userId，因为前端传过来的就是当前用户的计划
//        boolean removed = planService.remove(new LambdaQueryWrapper<Plan>().eq(Plan::getPlanId, planId));
//        if (!removed)
//            throw new BusinessException("删除失败");
//        return ResultUtil.success("删除成功");
//    }


//    /**
//     * 获取所有计划
//     * @return 返回计划结果
//     * 需要做分页查询
//     */
//    @GetMapping("/getAllPlans")
//    public ResultUtil getAllPlans() {
//        Long userId = SecurityUtils.getUserId();
//        LambdaQueryWrapper<Plan> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(Plan::getUserId, userId);
//        List<Plan> planList = planService.list(queryWrapper);
//        return ResultUtil.success(planList);
//    }
//
//    /**
//     * 获取已完成计划
//     * @return 返回已完成计划结果
//     * 需要做分页查询
//     */
//    @GetMapping("/getIsCompletePlan")
//    public ResultUtil getIsCompletePlan() {
//        Long userId = SecurityUtils.getUserId();
//        LambdaQueryWrapper<Plan> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(Plan::getUserId, userId);
//        queryWrapper.eq(Plan::getIsSuccess, 1);
//        List<Plan> planList = planService.list(queryWrapper);
//        return ResultUtil.success(planList);
//    }
//
//    /**
//     * 获取未完成计划
//     * @return 返回未完成计划结果
//     * 需要做分页查询
//     */
//    @GetMapping("/getIsNotCompletePlan")
//    public ResultUtil getIsNotCompletePlan() {
//        Long userId = SecurityUtils.getUserId();
//        LambdaQueryWrapper<Plan> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(Plan::getUserId, userId);
//        queryWrapper.eq(Plan::getIsSuccess, 0);
//        List<Plan> planList = planService.list(queryWrapper);
//        return ResultUtil.success(planList);
//    }



    /**
     * 获取计划（分页）
     * @param planQuery 计划查询对象
     * @return 返回计划结果
     */
    @GetMapping("/page/getPlans")
    public ResultUtil getPlansByPage (PlanQuery planQuery) {
        Long userId = SecurityUtils.getUserId();
        PageDTO<PlanVO> planVOPageDTO = planService.queryPlanPage(userId, planQuery);
        return ResultUtil.success(planVOPageDTO);
    }

    @GetMapping("/{planId}/showLearnTime")
    public ResultUtil showLearnTime (@PathVariable @NotNull(message = "计划id不能为空") Long planId) {
        Map<String,Integer> showLearnTimeVO = planService.showLearnTime(planId);
        return ResultUtil.success(showLearnTimeVO);
    }

    /**
     * 修改计划时间
     * @param updatePlanTimeRequest
     * @return
     */
    @RequestLock(prefix = "updateLearnTime:",expire = 3)
    @PutMapping("/updateLearnTime")
    public ResultUtil updateLearnTime (@RequestKeyParam @RequestBody UpdatePlanTimeRequest updatePlanTimeRequest) {
        boolean success = planService.updatePlanTime(updatePlanTimeRequest);
        if (!success){
            return ResultUtil.error("修改失败");
        }
        return ResultUtil.success("修改成功");
    }

    /**
     * 修改计划的当前章节
     * @param updateCurrentModuleRq
     * @return
     */
    @RequestLock(prefix = "updateCurrentModule:",expire = 3)
    @PutMapping("/updateCurrentModule")
    public ResultUtil updateCurrentModule (@RequestKeyParam @RequestBody UpdatePlanCurrentModuleRequest updateCurrentModuleRq) {
        boolean success = planService.updateCurrentModule(updateCurrentModuleRq);
        if (!success){
            return ResultUtil.error("修改失败");
        }
        return ResultUtil.success("修改成功");
    }

}
